#include "hx711.h"
#include "gpio.h"

uint32_t weight_first = 0;   // 去皮偏移
uint32_t weight_real = 0;    // 当前值
float hx711_scale = 100.0f;  // 缩放比例，可校准

uint32_t ReadCount(void)
{
    uint32_t Count = 0;
    uint8_t i = 0;

    HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET);

    while (HAL_GPIO_ReadPin(HX711_DT_GPIO_Port, HX711_DT_Pin));  // 等待DT准备好

    for (i = 0; i < 24; i++)
    {
        HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET);
        Count = Count << 1;
        HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET);

        if (HAL_GPIO_ReadPin(HX711_DT_GPIO_Port, HX711_DT_Pin))
            Count++;
    }

    // 第25个脉冲，设置增益为128（通道A）
    HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET);

    // 补码处理
    if (Count & 0x800000)
        Count |= ~0xFFFFFF;

    return Count;
}

void HX711_Tare(void)
{
    weight_first = ReadCount();  // 保存去皮值
}

// 滑动平均滤波
#define SLIDE_WIN_SIZE 5
float HX711_ReadWeight(void)
{
    static float slide_buf[SLIDE_WIN_SIZE] = {0};
    static int slide_idx = 0;
    static int slide_cnt = 0;
    float slide_sum = 0;

    int32_t raw = ReadCount();
    int32_t value = raw - weight_first;
    if (value < 0)
        value = -value;
    float cur = value / hx711_scale;

    // 存入滑动窗口
    slide_buf[slide_idx] = cur;
    slide_idx = (slide_idx + 1) % SLIDE_WIN_SIZE;
    if (slide_cnt < SLIDE_WIN_SIZE) slide_cnt++;

    // 求平均
    for (int i = 0; i < slide_cnt; i++) {
        slide_sum += slide_buf[i];
    }
    return slide_sum / slide_cnt;
}

void HX711_SetScale(float scale)
{
    hx711_scale = scale;
}
